﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.RmqWorkers
{
    public class OrderPickupingChkWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPickupingChkWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new OrderPickupingChkConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.OrderType == OrderType.挂号订单)
                    {
                        return ProcessRegOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.门诊缴费订单)
                    {
                        return ProcessBillOrder(msg.OrderId, channel);
                    }


                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(500);
                }
            }
        }

        private ConsumedResult ProcessRegOrder(int orderId, WrapperChannel channel)
        {
            OrderSummary order;
            using (var ctx = new HzfyWeiXinEntities())
            {
                order = ctx.ApptOrder.Where(x => x.Id == orderId).Select(x => new OrderSummary
                {
                    OrderNo = x.OrderNo,
                    OrderType = x.OrderType,
                    Id = x.Id,
                    SumFee = x.SumFee,
                    WxUserId = x.WxUserId,
                    WxTransactionId = x.WxTransactionId,
                    RegDate = x.RegDate,
                    StartTime = x.StartTime,
                    EndTime = x.EndTime,
                    DeptName = x.DeptName,
                    DoctorName = x.DoctorName,
                    CardNo = x.CardNo,
                    CardType = x.CardType
                }).FirstOrDefault();

                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
            }

            //执行查询挂号状态操作
            var regChkRequest = new GetOrderStatusRequest();
            regChkRequest.OrderId = order.OrderNo;

            GetOrderStatusResponse regChkResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetOrderStatus", regChkRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                regChkResponse = responseMsg.Content.ReadAsAsync<GetOrderStatusResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内查询取号状态Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new ConsumedResult
                {
                    Ack = false,
                    Delay = 60 * 1000
                };
            }
            if (regChkResponse.ResultCode != "0")
            {
                // 取号失败
                using (var _ctx = new HzfyWeiXinEntities())
                {
                    SqlParameter[] para =
                        {
                    new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号失败.ToInt32()),
                    new SqlParameter("@OrderId", order.Id),
                     };
                    _ctx.Database.ExecuteSqlCommand(
                        "Update ApptOrder set OrderStatus= @OrderStatus where Id=@OrderId", para);
                }

                if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                {
                    // RMQ 取消预约 
                    var unapptingProducer = new OrderUnapptingProducer();
                    unapptingProducer.Publish(new OrderUnapptingMsg
                    {
                        OrderType = Rmq.Center.OrderType.挂号订单,
                        OrderId = order.Id,
                        Reason = 2
                    });
                }

                // RMQ 执行取消锁号操作
                var unlockingProducer = new OrderUnlockingProducer();
                unlockingProducer.Publish(new OrderUnlockingMsg
                {
                    OrderType = OrderType.挂号订单,
                    OrderId = orderId
                });

                // RMQ 发送用户挂号失败通知
                var msgProducer = new UserMessageProducer();
                msgProducer.Publish(new UserMessageMsg
                {
                    Type = UserMessageType.挂号失败通知,
                    OrderId = order.Id
                });

                // RMQ 执行退费操作
                if (order.SumFee > 0)
                {
                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                    {
                        OrderType = OrderType.挂号订单,
                        OrderId = order.Id
                    });
                }
            }
            else
            {
                // 查询结果为已取号
                if (regChkResponse.Status == "1" || regChkResponse.Status == "2")
                {
                    using (var ctx = new HzfyWeiXinEntities())
                    {
                        var para = new SqlParameter[]
                        {
                            new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号成功.ToInt32()),
                            new SqlParameter("@RegNo", regChkResponse.SeqCode),
                            new SqlParameter("@Location", regChkResponse.Address),
                            new SqlParameter("@VisitNo", regChkResponse.AdmNo),
                            new SqlParameter("@FetchTime", DateTime.Now),
                            new SqlParameter("@OrderId", order.Id)
                        };
                        ctx.Database.ExecuteSqlCommand("Update ApptOrder set OrderStatus= @OrderStatus," +
                                                   "RegNo = @RegNo,Location=@Location,VisitNo=@VisitNo," +
                                                   "FetchTime=@FetchTime where Id=@OrderId", para);
                    }

                    // RMQ 发送用户挂号成功通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        Type = UserMessageType.挂号成功通知,
                        OrderId = order.Id
                    });

                    // RMQ 发送发货通知
                    if (order.SumFee > 0)
                    {
                        using (var ctx = new HzfyWeiXinEntities())
                        {
                            var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                            if (wxuser != null)
                            {
                                WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                                    "AP" + order.OrderNo,
                                    ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                        .ToString(), "1", "");
                            }
                        }
                    }
                }
                else
                {
                    // 取号失败
                    //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号失败.ToInt32();
                    //ctx.SaveChanges();
                    using (var _ctx = new HzfyWeiXinEntities())
                    {
                        SqlParameter[] para =
                        {
                                new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号失败.ToInt32()),
                                new SqlParameter("@OrderId", order.Id),
                            };
                        _ctx.Database.ExecuteSqlCommand(
                            "Update ApptOrder set OrderStatus= @OrderStatus where Id=@OrderId", para);
                    }

                    if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                    {
                        // RMQ 取消预约 
                        var unapptingProducer = new OrderUnapptingProducer();
                        unapptingProducer.Publish(new OrderUnapptingMsg
                        {
                            OrderType = Rmq.Center.OrderType.挂号订单,
                            OrderId = order.Id,
                            Reason = 2
                        });
                       
                    }
                    // RMQ 执行取消锁号操作
                    var unlockingProducer = new OrderUnlockingProducer();
                    unlockingProducer.Publish(new OrderUnlockingMsg
                    {
                        OrderType = OrderType.挂号订单,
                        OrderId = orderId
                    });

                    // RMQ 发送用户挂号失败通知
                    var msgProducer = new UserMessageProducer();
                    msgProducer.Publish(new UserMessageMsg
                    {
                        Type = UserMessageType.挂号失败通知,
                        OrderId = order.Id
                    });

                    // RMQ 执行退费操作
                    if (order.SumFee > 0)
                    {
                        var refundingProducer = new OrderRefundingPickupFailedProducer();
                        refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                        {
                            OrderType = OrderType.挂号订单,
                            OrderId = order.Id
                        });
                    }
                }
            }


            return new ConsumedResult
            {
                Ack = true
            };
        } 


        private ConsumedResult ProcessBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new HzfyWeiXinEntities())
            {

                var order = ctx.BillOrder.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                var request = new GetPayStatusRequest();
                request.CardNo = order.CardNo;
                request.TransNo = order.WxTransactionId;

                GetPayStatusResponse response;

                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPayStatus", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<GetPayStatusResponse>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内查询缴费单状态Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    return new ConsumedResult
                    {
                        Ack = false,
                        Delay = 60 * 1000
                    };
                }
               
                if (response.ResultCode != "0")
                {
                    // 缴费失败
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费失败.ToInt32();
                    ctx.SaveChanges();

                    // RMQ 发起缴费失败通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费失败通知
                    });

                    // RMQ 发起退款
                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                    {
                        OrderType = OrderType.门诊缴费订单,
                        OrderId = order.Id
                    });

                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
                else
                {
                    // 缴费成功
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();

                    order.Remark = response.ResultDesc;
                    //order.RealRcptNo = i.InvoiceNO;
                    order.FetchTime = DateTime.Now;
                    ctx.SaveChanges();

                    // RMQ 发起缴费成功通知
                    var messageProducer1 = new UserMessageProducer();
                    messageProducer1.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费成功通知
                    });
                    var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                    if (wxuser != null)
                    {
                        // RMQ 发送发货通知
                        //TenpayV2Helper.DoDeliverNotify(wxuser.OpenId, order.WxTransactionId,
                        //    "BL" + order.OrderNo, "1", "");
                        WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                        "BL" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                            .ToString(), "1", "");
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        public class OrderSummary
        {
            public string OrderNo { get; set; }
            public string OrderType { get; set; }
            public int Id { get; set; }
            public  string RegDate { get; set; }
            public string StartTime { get; set; }
            public string EndTime { get; set; }
            public string DeptName { get; set; }
            public string DoctorName { get; set; }
            public string CardNo { get; set; }

            public decimal? SumFee { get; set; }
            public long? WxUserId { get; set; }
            public string WxTransactionId { get; set; }
            public string CardType { get; internal set; }
        }
    }
}